/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.gidoo.cms.data;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.gidoo.cms.dbconnection.DatabaseConnectionException;

/**
 * Defines a section of the CMS. A section is a very like a context known from
 * Java Servlets. It is mounted to a specific URL. Access and manipulating rights
 * are done section-wise.
 * @author <a href="mailto:tho.krause@gmail.com">Thomas Krause</a>
 */
@Entity
@Table(
uniqueConstraints={
  @UniqueConstraint(columnNames={"url"}),
  @UniqueConstraint(columnNames={"position"})}
  )
public class CMSSection implements Serializable, Comparable<CMSSection> {
  
  private Long id;

  private String name;
  
  private String url;
  
  private Collection<RegisteredUser> editors;
    
  private Collection<RegisteredUser> publishers;
  
  private Folder rootFolder;
  
  private int position;
  
  /** Sets the unique ID */
  public void setId(Long id)
  {
    this.id = id;
  }

  /** Getter for the unique ID */
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId()
  {
    return id;
  }

  /**
   * Get the name of the folder. The name is <b>not</b> the URL. It may be used
   * to implement e.g. a menu.
   */
  @Column(nullable=false)
  public String getName()
  {
    return name;
  }

  /**
   * Sets the name of the folder. The name is <b>not</b> the URL. It may be used
   * to implement e.g. a menu.
   */
  public void setName(String name)
  {
    this.name = name;
  }

  /**
   * Get the URL. This is the unique URL. The section is "mounted" using the url. 
   */
  @Column(nullable=false)
  public String getUrl()
  {
    return url;
  }

  /**
   * Set the URL.
   */
  public void setUrl(String url)
  {
    if("/".equals(url))
    {
      this.url = ""; // this is not null :-)
    }
    else
    {
      this.url = url;
    }
  }
  
  
  /**
   * Get a list of all editors which have the right to edit in this section.
   */
  @ManyToMany
  @JoinTable(name="editing_rights")
  public Collection<RegisteredUser> getEditors()
  {
    return editors;
  }

  /** Set the list of all editors which have the right to edit in this section.*/
  public void setEditors(Collection<RegisteredUser> editors)
  {
    this.editors = editors;
  }
  
  /** 
   * Get a list of all publisher which have the right to publish changes made
   * by the editors in this section.
   */
  @ManyToMany
  @JoinTable(name="publishing_rights")
  public Collection<RegisteredUser> getPublishers()
  {
    return publishers;
  }
  /** 
   * Set the list of all publisher which have the right to publish changes made
   * by the editors in this section.
   */
  public void setPublishers(Collection<RegisteredUser> publishers)
  {
    this.publishers = publishers;
  }

  /** 
   * Get the folder which represents the root node in the folder structure
   * beginning at this section.
   */
  @OneToOne
  public Folder getRootFolder() throws DatabaseConnectionException
  {
    return rootFolder;
  }
  /** 
   * Set the folder which represents the root node in the folder structure
   * beginning at this section.
   */
  public void setRootFolder(Folder rootFolder)
  {
    this.rootFolder = rootFolder;
  }

  /** 
   * Get the position of this section among all sections.
   * 
   * First section has 0, second is 1 and so on. The position has
   * to be unique among all sections. 
   */
  @Column(nullable=false)
  public int getPosition()
  {
    return position;
  }
  
  /** 
   * Set the position of this section among all sections.
   * 
   * First section has 0, second is 1 and so on. The position has
   * to be unique among all sections. 
   */
  public void setPosition(int position)
  {
    this.position = position;
  }
  
  
  
  /**
   * Return a textual representation of the section. Normally this is equal
   * to {@link #getUrl} but if it is the root folder you will get a "/".
   */
  @Override
  public String toString()
  {
    if("".equals(getUrl()))
    {
      return "/";
    }
    else
    {
      return getUrl();
    }
  }

  /**
   * Checks wether the other object is also a section an the ID is the same.
   */
  @Override
  public boolean equals(Object obj)
  {
    if(obj == null)
      return false;
    if(obj instanceof CMSSection)
    {
      CMSSection other = (CMSSection) obj;
      if(other.getId() == this.getId())
      {
        return true;
      }
    }
     
    return false;
  }

  /**
   * Compares the two sections by doing a textual comparision on the result of
   * their {@link #toString} function.
   */
  public int compareTo(CMSSection o)
  {
    if(o == null || o.toString() == null)
      return -1;
    
    if(this.toString() == null)
      return 1;
    
    return this.toString().compareTo(o.toString());
  }
  
  
  
}
